package com.fauks.restful.utils;

import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class HttpClientUtil {

    public static final String RETURN_CODE_FAIL = "request_fail";
    private final static Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);
    private static final int timeout = 30000;
    /**
     * 每个主机最大连接数
     */
    private static final int maxConnectionsPerHost = 20;
    /**
     * 最大总共连接数
     */
    private static final int maxTotalConnection = 100;
    private static final String encoding = "UTF-8";

    private HttpClientUtil() {
    }

    /**
     * post请求
     *
     * @param url    请求地址
     * @param params 请求参数
     * @return 返回结果
     * @throws Exception
     */
    @SuppressWarnings("rawtypes")
    public static String postRequest(String url, Map<String, String> params) {
        return postRequest(url, null, params);
    }

    /**
     * post请求
     *
     * @param url    请求地址
     * @param header 请求头
     * @param params 请求参数
     * @return 返回结果
     * @throws Exception
     */
    @SuppressWarnings("rawtypes")
    public static String postRequest(String url, Map<String, String> header, Map<String, String> params) {
        String result = "";
        PostMethod postMethod = null;

        try {
            //创建连接
            HttpClient httpClient = new HttpClient(HttpClientUtilHolder.httpConnectionManager);
            // 设置编码
            httpClient.getParams().setContentCharset(encoding);
            httpClient.getParams().setHttpElementCharset(encoding);
            httpClient.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, encoding);

            postMethod = new PostMethod(url);

            //设置头信息

            for (Map.Entry<String, String> entry : header.entrySet()) {
                postMethod.setRequestHeader(entry.getKey(), entry.getValue());
            }


            //设置参数
            List<NameValuePair> list = new ArrayList<NameValuePair>();
            NameValuePair nameValuePair = null;
            Iterator iter = params.entrySet().iterator();
            while (iter.hasNext()) {
                Map.Entry entry = (Map.Entry) iter.next();
                String key = (String) entry.getKey();
                String val = (String) entry.getValue();
                nameValuePair = new NameValuePair(key, val);
                list.add(nameValuePair);
            }
            NameValuePair[] data = list.toArray(new NameValuePair[list.size()]);
            postMethod.setRequestBody(data);

            //请求
            logger.info("=================httpclient发起请求");
            httpClient.executeMethod(postMethod);
            logger.info("=================httpclient请求结束");
            result = postMethod.getResponseBodyAsString();
            logger.info("httpclient请求结果:{}", result);
        } catch (Exception e) {
            logger.error("=================httpclient请求异常：", e);
            result = RETURN_CODE_FAIL;
        } finally {
            if (postMethod != null) {
                //释放连接
                postMethod.releaseConnection();
            }
        }
        return result;

    }

    /**
     * post请求-没有参数名，只有参数值
     *
     * @param url  请求地址
     * @param body 请求参数
     * @return 返回结果
     * @throws Exception
     */
    public static String postRequestOfNoParamName(String url, String body) {
        String result = "";
        PostMethod postMethod = null;

        try {
            //创建连接
            HttpClient httpClient = new HttpClient(HttpClientUtilHolder.httpConnectionManager);
            // 设置编码
            httpClient.getParams().setContentCharset(encoding);
            httpClient.getParams().setHttpElementCharset(encoding);
            httpClient.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, encoding);

            postMethod = new PostMethod(url);
            postMethod.setRequestEntity(new StringRequestEntity(body, "", encoding));

            //请求
            httpClient.executeMethod(postMethod);
            result = postMethod.getResponseBodyAsString();
        } catch (Exception e) {
            logger.error("=================httpclient请求异常异常：", e);
            result = RETURN_CODE_FAIL;
        } finally {
            if (postMethod != null) {
                //释放连接
                postMethod.releaseConnection();
            }
        }
        return result;

    }

    public static String getRequest(String url) throws Exception {
        String result = "";
        GetMethod getMethod = null;
        try {
            //创建连接
            HttpClient httpClient = new HttpClient(HttpClientUtilHolder.httpConnectionManager);
            // 设置编码
            httpClient.getParams().setContentCharset(encoding);
            httpClient.getParams().setHttpElementCharset(encoding);
            httpClient.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, encoding);

            getMethod = new GetMethod(url);
            //请求
            int statusCode = httpClient.executeMethod(getMethod);
            if (statusCode == HttpStatus.SC_OK) {
                result = getMethod.getResponseBodyAsString();
            } else {
                result = RETURN_CODE_FAIL;
            }
        } catch (Exception e) {
            logger.error("=================httpclient请求异常异常：", e);
            //          result = RETURN_CODE_FAIL;
            result = null;
            throw new Exception(e.getMessage(), e);
        } finally {
            if (getMethod != null) {
                //释放连接
                getMethod.releaseConnection();
            }
        }
        return result;

    }

    /**
     * 单例创建httpConnectionManager.
     */
    private static class HttpClientUtilHolder {
        private static HttpConnectionManager httpConnectionManager = initConnectionManager();

        private static HttpConnectionManager initConnectionManager() {
            logger.info("initConnectionManager");
            httpConnectionManager = new MultiThreadedHttpConnectionManager();
            HttpConnectionManagerParams params = httpConnectionManager.getParams();
            params.setConnectionTimeout(timeout);
            params.setSoTimeout(timeout);
            params.setDefaultMaxConnectionsPerHost(maxConnectionsPerHost);
            params.setMaxTotalConnections(maxTotalConnection);
            return httpConnectionManager;
        }
    }

}